home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_200 / 255_01 / cega_io.asm < prev    next >
Encoding:
Assembly Source File  |  1988-03-28  |  10.3 KB  |  381 lines

  1.           page   80,132
  2.           page
  3. ;
  4. ;         Kent Cedola
  5. ;         2015 Meadow Lake Court
  6. ;         Norfolk, Virginia  23518
  7. ;
  8.  
  9. dgroup    group  _data
  10.  
  11. _data     segment word public 'data'
  12.           assume ds:dgroup
  13.           public _gdcolor,_gdgseg
  14.  
  15. _gdcolor  db     0
  16. _gdgseg   dw     0A000h
  17.  
  18. _data     ends
  19.  
  20. _text     segment byte public 'code'
  21.  
  22.           assume cs:_text,ds:dgroup
  23.           public _egacolor,_egaline,_egaplot,_egafillrect
  24.  
  25. _egacolor proc   near
  26.           push   bp
  27.           mov    bp,sp
  28.  
  29.           mov    al,[bp+4]
  30.           mov    _gdcolor,al
  31.  
  32.           pop    bp
  33.           ret
  34. _egacolor endp
  35.  
  36. _egaline  proc   near
  37.  
  38.           push   bp
  39.           mov    bp,sp
  40.           push   si
  41.           push   di
  42.  
  43.           call   ega_init
  44.  
  45.           mov    cx,[bp+4]             ; Load starting X coordinate (X1)
  46.           mov    bx,[bp+6]             ; Load starting Y coordinate (Y1)
  47.  
  48.           cmp    cx,[bp+8]             ; Is X1 <= X2?
  49.           jbe    noxchg                ;   Yes, continue
  50.           xchg   [bp+8],cx             ;   No, then switch (X1,Y1) with (X2,Y2)
  51.           xchg   [bp+10],bx            ;     ...
  52.           mov    [bp+4],cx
  53.           mov    [bp+6],bx
  54. noxchg:
  55.           call   bit_addr
  56.  
  57.           mov    ah,_gdcolor
  58.  
  59.           mov    bx,[bp+8]             ; Load ending X coordinate (X2)
  60.           mov    di,[bp+10]            ; Load ending Y coordinate (Y2)
  61.  
  62.           sub    bx,[bp+4]             ; Compute Delta X := X2 - X1;
  63.           sub    di,[bp+6]             ; Compute Delta Y := Y2 - Y1;
  64.  
  65.           push   bp
  66.           or     di,di
  67.           jns    line01
  68.           neg    di
  69.           cmp    di,bx
  70.           ja     lineoct7
  71.           jmp    short lineoct8
  72. line01:
  73.           cmp    di,bx
  74.           ja     lineoct2
  75.  
  76. lineoct1:
  77.           mov    cx,bx                 ; Count Down = DX
  78.           mov    bp,bx                 ; Error Register = -DX/2
  79.           shr    bp,1                  ;   ...
  80.           neg    bp                    ;   ...
  81. lineoct1L:
  82.           out    dx,al
  83.           cmp    byte ptr es:[si],0
  84.           mov    es:[si],ah
  85.           dec    cx
  86.           js     linedone
  87.           ror    al,1
  88.           adc    si,0
  89.           add    bp,di
  90.           js     lineoct1L
  91.           add    si,80
  92.           sub    bp,bx
  93.           jmp    short lineoct1L
  94.  
  95. lineoct2:
  96.           mov    cx,di                 ; Count Down = DY
  97.           mov    bp,di                 ; Error Register = -DY/2
  98.           shr    bp,1                  ;   ...
  99.           neg    bp                    ;   ...
  100. lineoct2L:
  101.           out    dx,al
  102.           cmp    byte ptr es:[si],0
  103.           mov    es:[si],ah
  104.           dec    cx
  105.           js     linedone
  106.           add    si,80
  107.           add    bp,bx
  108.           js     lineoct2L
  109.           ror    al,1
  110.           adc    si,0
  111.           sub    bp,di
  112.           jmp    short lineoct2L
  113.  
  114. lineoct7:
  115.           mov    cx,di                 ; Count Down = -DY
  116.           mov    bp,di                 ; Error Register = DY/2
  117.           shr    bp,1                  ;   ...
  118.           neg    bp                    ;
  119. lineoct7L:
  120.           out    dx,al
  121.           cmp    byte ptr es:[si],0
  122.           mov    es:[si],ah
  123.           dec    cx
  124.           js     linedone
  125.           sub    si,80
  126.           add    bp,bx
  127.           js     lineoct7L
  128.           ror    al,1
  129.           adc    si,0
  130.           sub    bp,di
  131.           jmp    short lineoct7L
  132.  
  133. lineoct8:
  134.           mov    cx,bx                 ; Count Down = DX
  135.           mov    bp,bx                 ; Error Register = -DX/2
  136.           shr    bp,1                  ;   ...
  137.           neg    bp                    ;   ...
  138. lineoct8L:
  139.           out    dx,al
  140.           cmp    byte ptr es:[si],0
  141.           mov    es:[si],ah
  142.           dec    cx
  143.           js     linedone
  144.           ror    al,1
  145.           adc    si,0
  146.           add    bp,di
  147.           js     lineoct8L
  148.           sub    si,80
  149.           sub    bp,bx
  150.           jmp    short lineoct8L
  151.  
  152. linedone:
  153.           pop    bp
  154.  
  155.           call   ega_term
  156.  
  157.           pop    di
  158.           pop    si
  159.           pop    bp
  160.           ret
  161.  
  162. _egaline  endp
  163.  
  164. _egaplot  proc   near
  165.  
  166.           push   bp
  167.           mov    bp,sp
  168.           push   si
  169.           push   di
  170.  
  171.           call   ega_init
  172.  
  173.           mov    cx,[bp+4]
  174.           mov    bx,[bp+6]
  175.  
  176.           call   bit_addr
  177.  
  178.           out    dx,al                 ; Set mask byte to change only our bit
  179.           mov    al,es:[si]
  180.           mov    al,_gdcolor
  181.           mov    es:[si],al            ; Apply merge function to bit and store
  182.  
  183.           call   ega_term
  184.  
  185.           pop    di
  186.           pop    si
  187.           pop    bp
  188.           ret
  189. _egaplot  endp
  190.  
  191. _egafillrect proc near
  192.  
  193.           push   bp
  194.           mov    bp,sp
  195.           push   si
  196.           push   di
  197.  
  198.           call   ega_init
  199.  
  200.           mov    ax,[bp+4]             ; Load X1 coordinate of current frame
  201.           mov    bx,[bp+6]             ; Load Y1 coordinate of current frame
  202.           mov    di,[bp+8]             ; Load X2 coordinate of current frame
  203.           mov    si,[bp+10]            ; Load Y2 coordinate
  204.  
  205.           cmp    ax,di
  206.           jbe    fill01
  207.           xchg   ax,di
  208. fill01:
  209.           cmp    bx,si
  210.           jbe    fill02
  211.           xchg   bx,si
  212. fill02:
  213.  
  214.           MOV    cx,ax                 ; Determine the first mask byte
  215.           AND    cl,7                  ;   ...
  216.           mov    dl,0FFh
  217.           shr    dl,cl
  218.           mov    [bp+4],dl
  219.  
  220.           MOV    cx,DI                 ; Determine the second (last) mask byte
  221.           AND    cl,7                  ;   ...
  222.           mov    dl,080h
  223.           sar    dl,cl
  224.           mov    [bp+6],dl
  225.  
  226.           mov    cx,si                 ; Load Y2 corrdinate of current frame
  227.  
  228.           MOV    DX,AX                 ; Determine width in bytes
  229.           SHR    DX,1                  ; Convert X1 to a byte count
  230.           SHR    DX,1                  ;   ...
  231.           SHR    DX,1                  ;   ...
  232.           SHR    DI,1                  ; Convert X2 to a byte count
  233.           SHR    DI,1                  ;   ...
  234.           SHR    DI,1                  ;   ...
  235.           SUB    DI,DX                 ; Width + 1
  236.           JNZ    clear01
  237.           PUSH   AX
  238.           MOV    AL,[bp+6]
  239.           AND    AL,[bp+4]
  240.           MOV    [bp+8],AL
  241.           POP    AX
  242. clear01:
  243.           DEC    DI                    ; Width
  244.           SUB    CX,BX                 ; Determine the Height of the frame
  245.           INC    CX                    ;   ...
  246.  
  247.           MOV    SI,AX                 ;
  248.           SHR    SI,1                  ; Divide X corrdinate by eight and
  249.           SHR    SI,1                  ;   ...
  250.           SHR    SI,1                  ;   ...
  251.           mov    ax,bx
  252.           shl    ax,1
  253.           shl    ax,1
  254.           add    ax,bx
  255.           add    ax,0A000h
  256.           mov    es,ax
  257.  
  258. ;         CX     Height
  259. ;         SI     Byte Offset
  260. ;         DI     Width
  261. ;         ES     'A000'
  262.  
  263.           mov    dx,03CEh
  264.           mov    al,8
  265.           out    dx,al
  266.           inc    dx
  267.  
  268.           MOV    AH,_gdcolor
  269.  
  270.           MOV    AL,[bp+4]
  271.           OUT    DX,AL
  272.           CALL   col_fill
  273.           OR     DI,DI
  274.           JS     L3
  275.           JZ     L2
  276.           MOV    AL,0FFh
  277.           OUT    DX,AL
  278. L6:
  279.           CALL   col_fill
  280.           DEC    DI
  281.           JNZ    L6
  282. L2:
  283.           MOV    AL,[bp+6]
  284.           OUT    DX,AL
  285.           CALL   col_fill
  286. L3:
  287.           jmp    short done
  288.  
  289. ;         AH     Color
  290. ;         CX     Height
  291. ;         DX     '03CF'
  292. ;         SI     Byte Offset
  293. ;         ES     'A000'
  294.  
  295. col_fill:
  296.           PUSH   CX
  297.           PUSH   SI
  298. col_f01:
  299.           MOV    AL,ES:[SI]
  300.           MOV    ES:[SI],AH
  301.           ADD    SI,80
  302.           LOOP   col_f01
  303.  
  304.           POP    SI
  305.           POP    CX
  306.           INC    SI
  307.           RET
  308.  
  309. done:
  310.           call   ega_term
  311.  
  312.           pop    di
  313.           pop    si
  314.           pop    bp
  315.           ret
  316.  
  317. _egafillrect endp
  318.  
  319. ega_init  proc   near
  320.  
  321.           mov    dx,03CEh              ; Load address of EGA graphic controller
  322.           mov    al,_gdcolor           ; Load current color setting
  323.           or     al,al                 ; Is the merge (xor) bit set?
  324.           jns    nomerge               ;   No, jump over merge code
  325.           mov    ax,01803h             ;   Yes, load xor merge setting
  326.           out    dx,ax                 ;     Set the EGA hardware register
  327. nomerge:
  328.           mov    ax,00205h             ; Load parameters for write mode #2
  329.           out    dx,ax                 ; Set the graphic controller write mode
  330.  
  331.           mov    al,08h                ;
  332.           out    dx,al                 ;
  333.           inc    dx                    ;
  334.  
  335.           mov    es,_gdgseg
  336.  
  337.           ret
  338. ega_init  endp
  339.  
  340. ega_term  proc   near
  341.  
  342.           mov    dx,03CEh
  343.           mov    ax,00003h
  344.           out    dx,ax
  345.           mov    al,005h
  346.           out    dx,ax
  347.           mov    ax,0FF08h
  348.           out    dx,ax
  349.  
  350.           ret
  351.  
  352. ega_term  endp
  353.  
  354.  
  355. ;         CX,BX  (X,Y)
  356.  
  357. bit_addr  proc   near
  358.  
  359.           mov    si,bx                 ; Compute SI = Y * 80 for row offset
  360.           shl    si,1                  ;   ... (SI = Y * 2)
  361.           shl    si,1                  ;   ... (SI = Y * 4)
  362.           add    si,bx                 ;   ... (SI = Y * 5)
  363.           shl    si,1                  ;   ... (SI = Y * 10)
  364.           shl    si,1                  ;   ... (SI = Y * 20)
  365.           shl    si,1                  ;   ... (SI = Y * 40)
  366.           shl    si,1                  ;   ... (SI = Y * 80)
  367.           mov    bx,cx                 ; Compute BX = X / 8 for column offset
  368.           shr    bx,1                  ;   ... (BX = X / 2)
  369.           shr    bx,1                  ;   ... (BX = X / 4)
  370.           shr    bx,1                  ;   ... (BX = X / 8)
  371.           add    si,bx                 ; Compute BX = BX + SI, first byte
  372.  
  373.           and    cl,7                  ; Compute AL = starting bit mask
  374.           mov    al,080h               ;   ... load default of bit 0
  375.           ror    al,cl                 ;   ... rotate to the starting bit mask
  376.  
  377.           ret
  378. bit_addr  endp
  379.  
  380. _text     ends
  381.           end